"use strict";

app.directive("infiniteScroll", ["$rootScope", "$window", "$timeout", "$q", function ($rootScope, $window, $timeout, $q) {
    return {
        scope: {
            infiniteScroll: "&",
            items: "=",
            skip: "=",
            maxBottom: "="
        },
        link: function (scope, elements, attrs) {
            $window = angular.element($window);
            var element = elements[0];
            var oldSkip = 0;

            if (!scope.items) throw new Error("infinite-scroll-items must be defined.");
            //scope.skip = scope.skip || -1;
            scope.maxBottom = scope.maxBottom || 0;

            //scope.$watch(function () {
            //    return scope.items;
            //}, function (newVal, oldVal) {
            //    if (newVal == oldVal) return;
            //    console.log("watch items", newVal, oldVal);
            //    oldSkip = -1;
            //    first = true;
            //    return invokePaging();
            //});

            scope.$watch(function () {
                return scope.skip;
            }, function (newVal, oldVal) {

                //console.log("inifiniteScroll. skip has change newVal", newVal, "oldVal", oldVal);

                oldSkip = oldVal;
                console.log("skip has changed", newVal);
                if (newVal == 0) return;

                return invokePagingIfNeeded();

                //return invokePaging().then(function () { //call 1 or many invokePaging
                //    invokePagingIfNeeded();
                //});
                //else console.log("shouldScroll == false");
            });

            var shouldScroll = function () {
                var windowHeight = document.documentElement.clientHeight;
                var elementBottom = element.getBoundingClientRect().bottom;
                //console.log("shouldScroll", elementBottom - windowHeight < scope.maxBottom);
                console.log("shouldScroll ->", elementBottom - windowHeight < scope.maxBottom, "elementBottom", elementBottom, "windowHeight", windowHeight, "maxBottom", scope.maxBottom, "element", element, "getBoundingClientRect", element.getBoundingClientRect(), "offsetHeight", element.offsetHeight);
                return elementBottom - windowHeight < scope.maxBottom;
            };


            var invokePaging = function () {
                return $timeout(function () {
                    if (oldSkip == scope.skip) return;
                    oldSkip = scope.skip;
                    console.log("invokePaging");
                    return scope.infiniteScroll();
                });
            };

            var invokePagingIfNeeded = function () {
                return $timeout(function () {
                    console.log("invokePagingIfNeeded");
                    if (shouldScroll()) {
                        console.log("shouldScroll => invokePaging needed");
                        return invokePaging().then(function () {
                            return invokePagingIfNeeded();
                        });
                    }
                    else console.log("shouldScroll completed");
                });
            };

            var handler = function (event) {
                console.log("invokeHandler skip:", scope.skip);
                if (!scope.skip) return;
                if (!shouldScroll()) return;
                invokePaging();
            };

            $window.on("scroll", handler);
            $window.on("resize", handler);
            scope.$on("$destroy", function () {
                $window.off("resize", handler);
                return $window.off("scroll", handler);
            });
            return $timeout((function () {
                return handler();
            }), 0);
        }
    };
}
]);